#!/usr/bin/env node

const fs = require("fs");
const xlsx = require("node-xlsx");
const child_process = require("child_process");
let gitBanchsArr = [];
let writedata = [];
var msg;
var startTime = new Date().getTime();
const version = "1.1.2"
var branchPatt = /^branch\=/
var emailPatt = /^email\=/
var versionPatt = /^(\-v|\--version)/
var mailPatt = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
var branchflag = false,emailflag = false,emailnumberflag=false;
var branchname = "",emailnumber = "";
var header = ["commit ID","Author","Time","Submit Information"];
var fileName = "";
var fileBarchName = "";
var branchIndex = 0;
var nowBranch;
var dta = timestampToStr(new Date().getTime(),"cn")
if (process.argv.length==3&&versionPatt.test(process.argv[2])) {
    console.log(version);
    return
}
child_process.exec('git branch', (error, stdout, stderr) => {
    if (!error) {
        // 成功
        var branchArr = stdout.trim().split("\n");
        nowBranch = branchArr.find(item=>item.startsWith("* ")).slice(2);
        gitBanchsArr = branchArr.map(item=>{
            if (item.startsWith("* ")) {
                return item.slice(2)
            }else{
                return item;
            }
        })
        console.log("nowBranch--->",nowBranch);
        console.log("AllBranchs--->",gitBanchsArr);
        if (process.argv.length>2) {
            for (let index = 2; index < process.argv.length; index++) {
                const words =  process.argv[index].trim();
                branchflag = branchPatt.test(words);
                emailflag = emailPatt.test(words)
                if (!branchflag&&!emailflag) {
                    console.error("The input parameter is incorrect")
                    return
                }   
                if (branchflag) {
                    branchname = words.split("=")[1]
                }
                if (emailflag) {
                    emailnumber = words.split("=")[1]
                    emailnumberflag = mailPatt.test(emailnumber)
                    if (!emailnumberflag) {
                        console.error("The email address is malformed")
                        return
                    }
                }
            }
            if (branchname) {
                var brancExit = gitBanchsArr.find(item=>item==branchname)
                if (!brancExit) {
                    console.log("The branch does not exist, try a other branch");
                    return
                }
                fileBarchName = branchname+" branch";
                if(emailnumber){
                    console.log(`getOwerInthisbranch->branchname=${branchname},emailnumber=${emailnumber}`);
                    getAutherCommitInBranch(branchname,emailnumber)
                }else{
                    console.log(`getAllCommitInthisbranch->branchname=${branchname}`);
                    branchToFile(branchname,1,0)
                }
                return
            }else{
                if(emailnumber){
                    console.log(`getOwerInAllbranch->emailnumber=${emailnumber}`);
                    fileBarchName = "All branch data"
                    AutherInAllBranch(emailnumber)
                    return
                }else{
                    throw new Error("input error")
                }
            }
        }
        else{
            console.log("get all branchs commit by all auther");
            fileBarchName = "All branch data"
            AllCommitInAllBranch()
        }
    } else {
        // 失败
        console.log(".git directory is node found,please using 'git init' to make it;")
    }
});
/**
 * 获取该分支emailnumber提交的信息
 * @param {*} branchname 
 * @param {*} emailnumber 
 */
function getAutherCommitInBranch(branchname,emailnumber){
    branchToFile(branchname,1,0,emailnumber)
}
function AllCommitInAllBranch(){
    for (let index = 0; index < gitBanchsArr.length; index++) {
        branchToFile(gitBanchsArr[index],gitBanchsArr.length,index,null)
    }
}
function AutherInAllBranch(emailnumber){
    for (let index = 0; index < gitBanchsArr.length;index++) { 
        branchToFile(gitBanchsArr[index],gitBanchsArr.length,index,emailnumber)
    }
}
function branchToFile(branch,length,index,emailnumber){
    var str="";
    if (emailnumber) {
        str = emailnumber;
    }
    child_process.exec(`git log ${branch}`, (error, stdout, stderr) => {
        branchIndex++;
        msg = [];
        if (!error) {
            var obj ={
                    name:branch,
                    data:[]
                }
            stdout =  stdout.trim()
            var msgarr = stdout.split("\n");
            let innerarr;
            for (let jndex = 0; jndex < msgarr.length; jndex++) {
                let element = msgarr[jndex].trim();
                if (jndex%6==0) {
                    if (jndex!= 0) {
                        msg.push(innerarr)
                    }
                    innerarr = [];
                }
                if (jndex%6!=3&&jndex%6!=5) {
                    if (jndex%6==0) {
                        // commitID
                        element = element.slice(7)
                    }
                    if (jndex%6==1) {
                        // Author
                        element = element.slice(8)
                    }
                    if (jndex%6==2) {
                        // Date
                        let GMTDate = element.slice(5).trim()
                        element = timestampToStr(GMTDate,"en")
                    }
                    if (jndex%6==4) {
                        // log
                    }
                    innerarr.push(element)
                }
            }
            console.log(`Analyzing branch ${branchIndex} of ${length}`)
            if (emailnumber) {
                    var arr =[];
                    for (let jndex = 0; jndex < msg.length; jndex++) {
                        if (msg[jndex][3]==`\<${emailnumber}\>`) {
                            arr.push(msg[jndex])
                        }
                    }
                    var endTime = new Date().getTime(), total;
                    total = endTime-startTime
                    if (arr.length==0) {
                        endTime = new Date().getTime();
                        console.log(`There is no submission information from user ${emailnumber} under branch ${branch}, time ${dta}, time ${total}ms`);
                        return
                    }
                    obj.data=arr;
                }else{
                    obj.data=msg;
                }
                writedata.push(obj)
                if (index==length-1) {
                    for (let jndex = 0; jndex < writedata.length; jndex++) {
                        let arr = writedata[jndex].data
                        arr.unshift(header)
                        writedata[jndex].data = arr;
                    }
                    var buffer = xlsx.build(writedata);
                    var endTime = new Date().getTime();
                    fileName =str + fileBarchName + timestampToStr(endTime,"cn")
                    var total = endTime-startTime
                    fs.writeFile(`${fileName}.xlsx`,buffer,function(err){
                        if (!err) {
                            console.log(`${str} has been successfully written, shared during ${total} ms`);
                        }
                    })
                }
        }
    })
}
function timestampToStr(timestamp,lang){
    let date = new Date(new Date(timestamp).getTime());
    let Year = date.getFullYear();
    let Moth = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1);
    let Day = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
    let Hour = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours());
    let Minute = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes());
    let Sechond = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
    let  GMT="";
    if (lang=="cn") {
        GMT =  Year + '年' + Moth + '月' + Day + '日'+ Hour +'时'+ Minute  + '分' + Sechond+ '秒';
    }else{
        GMT=  Year + '-' + Moth + '-' + Day + ' '+ Hour +':'+ Minute  + ':' + Sechond;
    }
    return GMT
}